#include "precompiled.h"
#include "holypaladin.h"
using namespace std;
using namespace weo::engine::item;
using namespace weo::engine::character::paladin;

Holy::Holy()
{
    Healer::Init();
    m_Classnr = weo::engine::character::Character::isAllowed("Paladin");
    m_Basevalues.push_back(Attribute("Agility",79));
    m_Basevalues.push_back(Attribute("Intellect",95));
    m_Basevalues.push_back(Attribute("Strength",123));
    m_Basevalues.push_back(Attribute("Stamina",118));
    m_Basevalues.push_back(Attribute("Spirit",88));
    m_Basevalues.push_back(Attribute("CritSpellRating",3.3f*CritSpellRating));
    m_Basevalues.push_back(Attribute("Health",3197)); // health
    m_Basevalues.push_back(Attribute("Mana",2673)); // mana
    // talents
    m_Basevalues.push_back(Attribute("CritSpellRating",5.0f*CritSpellRating));
    m_Equip.Mode(0);
    BOOST_FOREACH(Attribute attr, m_Basevalues)
    {
        handleAttribute(attr);
    }
    // base settings finished
}
float Holy::evaluateTF()
{
    float runtime = 600;
    float time = runtime;
    float fol7cost = 180;
    float fol7heal = 475;
    float spellcrit = m_Equip[12] / CritSpellRating;
    float manaregic = m_Equip[21];
    float haste = m_Equip[13] / HasteSpellRating;
    float bol = 185;
    if(m_Equip.hasSpecial(1387251)) // libram of souls redeemed
    {
        bol += 105;
    }
    float manaregooc = (m_Equip[21] + 5 * 0.00932715221261f * std::sqrt(m_Equip[2]) * m_Equip[5])/5.0f;
    float fol7crit = spellcrit / 100.0f;
    float fol7casttime = 1.5f/(1+haste/100.0f);
    float fol7mana = max<float>(fol7cost * (1 - fol7crit * 0.6f) - (manaregic/5.0f) * fol7casttime, 1);
    float count = m_Equip[35] / fol7mana;
    float castuseratio = (manaregooc * fol7casttime ) / fol7mana;
    time -= count * fol7casttime + max<float>(5 * castuseratio, 5);
    time = max<float>(time, 0);
    float regtime = 0;
    if(time > 0)
    {
        regtime = time / (castuseratio + 1);
        regtime = min<float>(regtime, 0.3f * runtime);
        time -= regtime;
    }
    float hlight = 1.12f;
    if(m_Equip.hasSpecial(1432524)) // t6 4p
    {
        hlight *= 1.05f;
    }
    count += floor((regtime * manaregooc) / fol7mana);
    count = min<float>(count, (runtime - regtime) / fol7casttime);
    float healfol7 = hlight * count * (fol7heal + bol + m_Equip[20] * (1.5f / 3.5f)); // no healcrits
    return m_CondFactor * healfol7 / runtime;
}
void Holy::filterEquip(std::vector<std::vector<const weo::engine::item::Item*>>& items)
{
    for(unsigned int i = 0;i<10;i++)
    {
        int subtype = 3;
        if(i == 1 || i == 3)
        {
            vector<const Item*> temp = m_Database->getPtrbyType(1,i+1);
            items.push_back(temp);
        }
        else
        {
            vector<const Item*> temp = m_Database->getPtrbyType(1,i+1,4); // cloth		
            items.push_back(temp);
        }
    }
    items.push_back(m_Database->getPtrbyType(2,0));
    items.push_back(m_Database->getPtrbyType(2,0));
    items.push_back(m_Database->getPtrbyType(3,0));
    items.push_back(m_Database->getPtrbyType(3,0));
    // main hand weapons
    vector<const Item*> mainhand;
    for(int i = 1;i<3;i++)
    {
        for(int j = 1;j<3;j++)
        {
            vector<const Item*> weapon = m_Database->getPtrbyType(4,j,i);
            vector<const Item*>::iterator it;
            for(it=weapon.begin();it!=weapon.end();it++)
            {
                mainhand.push_back(*it);
            }
        }
    }
    //offhand
    vector<const Item*>::iterator it;
    vector<const Item*> offhand;
    vector<const Item*> shield = m_Database->getPtrbyType(1,11);
    vector<const Item*> ohand = m_Database->getPtrbyType(1,12);
    for(it=shield.begin();it!=shield.end();it++)
    {
        offhand.push_back(*it);
    }
    for(it=ohand.begin();it!=ohand.end();it++)
    {
        offhand.push_back(*it);
    }
    items.push_back(mainhand);
    items.push_back(offhand);
    items.push_back(m_Database->getPtrbyType(4,5,16)); // relicts
    items.push_back(m_Database->getPtrbyType(5,0));
    Healer::filterEquip(items);
}
void Holy::handleAttribute(const Attribute& attr)
{
    switch(attr.Type())
    {
    case 2:
        Healer::handleAttribute(Attribute(attr.Type(),attr.Value()*1.1f)); 
        handleAttribute(Attribute(20,attr.Value() * (m_HasBok ? 1.1f : 1.0f) * 1.1f * 0.35f));
        break;
    default:
        Healer::handleAttribute(attr);
        break;
    }
}
